-- Symmetric Nearest Neighbour as described by Hardwood et al in Pattern
-- recognition letters 6 (1987) pp155-162.

function snn(radius)
local x,y
for y=0, height-1 do
	for x=0, width-1 do
	    local sum=0.0
	    local count=0.0
	    local u,v
	    
	    local valueC = get_value (x,y)
	    
	    for v=-radius,radius do
	      for u=-radius,radius do
	         local valueA = get_value (x+u,y+v)
	         local valueB = get_value (x-u,y-v)
	         
	         if (math.abs(valueC-valueA) <
	             math.abs(valueC-valueB)) then
               sum = sum + valueA
	         else
               sum = sum + valueB	         
	         end
	         count = count + 1	         
	      end
	    end
		set_value (x,y, sum/count)
	end
	progress (y/height)
end
flush()
end

-- snn(6)

-- and a color version operating in CIE Lab 

function deltaE(l1,a1,b1,l2,a2,b2)
  return math.sqrt( (l1-l2)*(l1-l2) + (a1-a2)*(a1-a2) + (b1-b2)*(b1-b2))
end

function snn_color(radius)
local x,y
for y=0, height-1 do
	for x=0, width-1 do
	    local sumL=0.0
	    local suma=0.0
	    local sumb=0.0
	    local count=0.0
	    local u,v
	    
	    local lc,ac,bc = get_lab (x,y)
	    
	    for v=-radius,radius do
	      for u=-radius,radius do
			 local l1,a1,b1 = get_lab (x+u,y+v)	         
	         local l2,a2,b2 = get_lab (x-u,y-v)
	         
	         if (deltaE(lc,ac,bc,l1,a1,b1) <
	             deltaE(lc,ac,bc,l2,a2,b2)) then	             
               sumL = sumL + l1
               suma = suma + a1
               sumb = sumb + b1
	         else
	           sumL = sumL + l2
               suma = suma + a2
               sumb = sumb + b2	         
	         end
	         count = count + 1	         
	      end
	    end
		set_lab (x,y, sumL/count, suma/count, sumb/count)
	end
	progress (y/height)
end
flush()
end

snn_color(6)